;	PDP-11 FLOATING POINT PACKAGE
;	FLOATING POINT SINE
;	FLOATING POINT COSINE
;	FLOATING POINT LOGARITHM
;	FLOATING POINT EXPONENTIAL
;	FLOATING POINT SQUARE ROOT
;	FLOATING POINT ARC-TANGENT
;
;	MODULES INCLUDED:
;	1. SIN
;	2. COS
;	3. LOG
;	4. EXP
;	5. SQRT
;	6. ATAN
;	7. M.INIT
;	8. M.SETU
;	9. M.FRAC
;	10. M.DOPO
;
;
;
;
R0	=	%0
R1	=	%1
R2	=	%2
R3	=	%3
R4	=	%4
R5	=	%5
SP	=	%6
PC	=	%7
SIN:	JSR PC,M.INIT		;CLEAR FLAGS, PUSH POINTERS
M.SIN1:	TST 2(R0)		;TEST Y
	BGE M.NOTN		;Y<0?
	MOV R0,R1
	JSR PC,NEGF		;YES. LET Y=-Y
	INC 4(SP)		;LET NFLAG=1
	BR M.NOTE
M.NOTN:	BNE M.NOTE		;Y=0?
M.EXIT:	ADD #6,SP		;YES. RESTORE SP TO STARTING POSITION
	RTS PC
M.NOTE:	MOV #M.PIE2-M.FRA1-2,R1	;LET Y=Y*(2/PI)
	JSR PC,M.FRAC	;COMPUTE FRACTIONAL PART. RESULT WILL BE IN DEST
;STACK HAS THE INT PART (NOT FLOATED),AND DESTINATION HAS THE
;FRACTIONAL PART (KNOWN AS F)
	MOV	(SP)+,R2
	BIC #177774,R2		;AND 11(BASE 2) WITH INT
	ASL R2
	ADD #M.TAB-.-6,R2		;COMPUTE ADDRESS OF TABLE OF BRANCHES
M.TTX:	ADD PC,R2
	ADD @R2,PC		;BRANCH TO PROPER PLACE
M.Q2:	MOV #M.ONE-.-6,R1		;LET F=-(F-1)
	ADD PC,R1
	MOV @SP,R0
	JSR PC,SUBF
M.Q3:	MOV @SP,R0		;LET F=-F
	MOV R0,R1
	JSR PC,NEGF
	BR M.EVAL
M.Q4:	MOV #M.ONE-.-6,R1
	ADD PC,R1
	MOV @SP,R0
	JSR PC,SUBF		;LET F=F-1
;DEST NOW EQUALS X. EVALUATE THE POLYNOMIAL
M.EVAL:	MOV @SP,R0		;GET DEST POINTER
	MOV #M.A11-.-6,R4	;POINTER TO CONSTANT TABLE
	ADD PC,R4
	MOV #6,R3		;NUMBER OF CONSTANTS
	JSR PC,M.SETU		;SET UP DOPOL
	JSR PC,M.DOPO
	TST 4(SP)		;WAS NFLAG SET?
	BEQ M.EXIT
	MOV @SP,R0
	MOV	R0,R1
	JSR PC,NEGF		;YES. LET DEST=-DEST
	BR	M.EXIT




COS:	JSR PC,M.INIT		;CLEAR FLAGS, PUSH POINTERS
	MOV #M.PI2-.-6,R1	
	ADD PC,R1
	JSR PC,ADDF		;LET Y=PI/2+Y
	MOV @SP,R0
	BR M.SIN1
ATAN:	CLR -(SP)		;CLEAR NFLAG
	JSR PC,M.INIT		;CLEAR AFLAG,PUSH POINTERS
	TST 2(R0)		;DOES X=0?
	BEQ M.TT9
	BGE M.P2		;X DOESN'T =0. IS  X<0?
	INC 6(SP)		;X IS MINUS. SET NFLAG
	MOV R0,R1		;LET X=-X
	JSR PC,NEGF
M.P2:	MOV #M.ONE-.-6,R1	;IS X>1, OR IS  X-1>0?
	ADD PC,R1
	MOV @SP,R0
	JSR PC,CMPF
	BGE M.P
	INC 4(SP)		;X IS >1. SET AFLAG
	MOV #M.ONE-.-6,R0	;LET X=1/X
	ADD PC,R0
	JSR PC,M.MOVE		;MOVE ONE ONTO THE STACK
	MOV SP,R0
	MOV 6(SP),R1
	JSR PC,DIVF
	MOV SP,R1		;MOVE RESULT BACK INTO DEST
	MOV 6(SP),R0
	JSR PC,MOVF
	ADD #6,SP		;POP PAST ONE
M.P:	MOV #M.OT32-.-6,R1	;IS X<2-SQT(3), OR IS X-[2-SQT(3)]<0?
	ADD PC,R1
	MOV @SP,R0
	JSR PC,CMPF
	BLE M.BR4
	CLR -(SP)		;IT IS. LET C=0
	CLR -(SP)
	CLR -(SP)
	BR M.EVA1
;LET X=[X*SQT(3)-1]/[X+SQT(3)]
;LET C=PI;6
M.BR4:	MOV #M.PI6-.-6,R0
	ADD PC,R0
	JSR PC,M.MOVE		;MOVE PI6 ONTO THE STACK
	MOV 6(SP),R0
	JSR PC,M.MOVE		;SAVE X ON STACK
	MOV #M.ROT3-.-6,R1
	ADD PC,R1
	JSR PC,MULF		;LET DEST=DEST*SQT(3)
	MOV 14(SP),R0
	MOV #M.ONE-.-6,R1	;LET DEST=DEST-1
	ADD PC,R1
	JSR PC,SUBF
;DEST NOW ='S X*SQT(3)-1
;COMPUTE X+SQT(3)
	MOV SP,R0
	MOV #M.ROT3-.-6,R1
	ADD PC,R1
	JSR PC,ADDF
	MOV 14(SP),R0		;DIVIDE DEST BY X+SQT(3)
	MOV SP,R1
	JSR PC,DIVF
	ADD #6,SP		;POP UP TO C
;EVAL THE POLYNOMIAL
M.EVA1:	MOV 6(SP),R0		;POINTER TO DEST
	MOV #M.TAB2-.-6,R4	;POINTER TOCONSTANT TABLE
	ADD PC,R4
	MOV #5,R3		;NUMBER OF CONSTANTS
	JSR PC,M.SETU		;SET UP DOPOL
	JSR PC,M.DOPO
	MOV SP,R1		;LET DEST=DEST+C
	MOV 6(SP),R0
	JSR PC,ADDF
	ADD #6,SP		;POP PAST C
	TST 4(SP)		;AFLAG=0?
	BEQ M.P6
	MOV @SP,R0		;NO.LET DEST=PI/2-DEST
	MOV #M.PI2-.-6,R1
	ADD PC,R1
	JSR PC,SUBF
	MOV @SP,R0
	MOV R0,R1
	JSR PC,NEGF
M.P6:	TST 6(SP)		;WAS NFLAG SET?
	BEQ M.TT9
	MOV @SP,R0
	MOV R0,R1
	JSR PC,NEGF		;LET DEST=-DEST
M.TT9:	ADD #10,SP
	CLV			;OUT WITH OVERFLOW ON A BIG MACHINE
	RTS PC
LOG:	JSR PC,M.INI2
	TST 2(R0)		;Y .LE. 0?
	BGT M.XY
M.YY:	TST -(SP)		;YES.
	JMP M.EROR
M.XY:	MOV R0,R1		;DOES Y=1?
	TST (R1)+
	BNE M.XX		;DOES LOW FRACTION=0?
	CMP (R1)+,#40000	;YES. DOES HIGH FRACTION =40000?
	BNE M.XX
	CMP (R1)+,#100001	;YES. DOES EXPONENT =1?
	BNE M.XX
	CLR (R0)+		;YES. CLEAR DESTINATION
	CLR (R0)+
	CLR (R0)+
	ADD #4,SP
	CLV			;NO OVERFLOW FOR THE BIG MACHINE
	RTS PC
M.XX:	MOV 4(R0),-(SP)		;LET N=EXP (Y)
	ADD	#100000,@SP	;COMPLEMENT TO TRUE NOTATION
	MOV	#100000,4(R0)	;LET EXP (Y)=0
	MOV SP,R1		;FLOAT N AND LEAVE RESULT ON STACK
	SUB #6,SP
	MOV SP,R0
	JSR PC,FLT
	MOV 10(SP),R0		;SAVE X ON STACK
	JSR PC,M.MOVE
	MOV #M.RT2B2-.-6,R1
	ADD PC,R1
	JSR PC,SUBF		;DEST=DEST-SQR(2)
	MOV SP,R0		;LET X(STK)=X(STK)+SQR(2)/2
	MOV #M.RT2B2-.-6,R1
	ADD PC,R1
	JSR PC,ADDF
	MOV 16(SP),R0		;LET DEST=DEST/X(STK)
	MOV SP,R1
	JSR PC,DIVF
	MOV #M.TABL-.-6,R4	;SET UP SETUP ROUTINE
	ADD PC,R4		;LOC OF CONSTANT TABLE
	MOV 16(SP),R0		;LOC OF DESTINATION
	MOV #4,R3		;NUMBER OF CONSTANTS.
	JSR PC,M.SETU
	JSR PC,M.DOPO		;EVALUATE THE POLYNOMIAL
	MOV 16(SP),R0		;LET DEST=DEST-(LN 2)/2
	MOV #M.LGB2-.-6,R1
	ADD PC, R1
	JSR PC,SUBF
	ADD #6,SP		;POP TO FLOATED N
	MOV SP,R0
	MOV #M.LOGE-.-6,R1	;LET N=N*LN 2
	ADD PC,R1
	JSR PC,MULF
	MOV SP,R1		;LET DEST=DEST+N
	MOV 10(SP),R0
	JSR PC,ADDF
M.OUT:	ADD #14,SP		;RESTORE SP TO ORIGINAL POSITION
	CLV			;CLEAR OVERFLOW 
	RTS PC

SQRT:	JSR PC,M.INIT		;CLEAR NFLAG,PUSH POINTERS.
	TST 2(R0)		;IS X<0?
	BEQ	M.BR3		;IF ZERO WE KNOW THE ANSWER NOW
	BGE M.BR1
	INC 4(SP)		;YES .SET NFLAG
	MOV R0,R1
	JSR PC,NEGF		;LET X=-X
M.BR1:	CLR 2(SP)		;CLEAR OFLAG
	MOV @SP,R0
	CMP	(R0)+,(R0)+
	ADD	#100000,@R0	;COMLPEMENT BIT 15
	ASR	@R0		;SHIFT EXP(X) ONCE RIGHT TO SEE IF IS ODD AND
	ADC	2(SP)		;LET OFLAT=CARRY BIT. IT DETERMINES ODDITY
	MOV @R0,-(SP)		;TO DIVIDE IT BY TWO. SAVE IT ON STACK
	MOV	#100000,@R0	;EXP(X)=0. THIS REDUCES X TO THE PROPER RANGE
	MOV 2(SP),R0		;SAVE X ON THE STACK
	JSR PC,M.MOVE
	MOV #M.BB-.-6,R1	;LET X=B*X
	ADD PC,R1
	JSR PC,MULF
	MOV 10(SP),R0
	MOV #M.AA-.-6,R1	;LET X=X+A
	ADD PC,R1
	JSR PC,ADDF
	JSR PC,M.APPR		;DO FIRST APPROXIMATION
	JSR PC,M.APPR		;DO SECOND ITERATION
	JSR	PC,M.APPR	;DO A THIRD APPROXIMATION
	ADD 6(SP),4(R0)	;ADD SAVED EXPOONENT TO EXP(DEST)
	ADD #10,SP
	TST 2(SP)		;WAS OFLAG SET
	BEQ M.BR2
	MOV #M.ROOT-.-6,R1	;YES. MULT BY SQT(2)
	ADD PC,R1
	JSR PC,MULF
M.BR2:	TST 4(SP)		;WAS NFLAG SET?
	BNE M.EROR
M.BR3:	JMP M.EXIT
M.EROR:	ADD #6,SP		;RESTORE SP TO ORIGINAL POSITION
	SEV			;SET V
	RTS PC
;SUBROUTINE PERFORMS AN APPROXIMATION
;OF THE FORM Y0=.5(Y0+X/Y0)
M.APPR:	MOV SP,R0
	TST (R0)+		;ADD 2 TO R0
	JSR PC,M.MOVE		;SAVE X ON STACK
	MOV SP,R0		;SET UP DESTINATION
	MOV 20(SP),R1		;SET UP SOURCE
	JSR PC,DIVF		;COMPUTE X/Y0
	MOV SP,R1
	MOV 20(SP),R0
	JSR PC,ADDF		;LET Y0=Y0+X/Y0
	MOV 20(SP),R0
	DEC 4(R0)
	ADD #6,SP
	CLV			;;COULD BE OVERFLOW ON A BIG MACHINE
	RTS PC
EXP:	JSR PC,M.INI2		;GET POINTERS
	CMP	4(R0),#100016	;IS EXP(Y)>14
	BLOS M.EHEE
	JMP M.YY		;YES. ERROR
M.EHEE:	MOV #M.LOG2-M.FRA1-2,R1	;NO.
	JSR PC,M.FRAC		;COMPUTE FRACTIONAL PART. RESULT IS IN DEST.
	MOV 2(SP),R0		;LET Y=Y*[LN(2)/2]
	MOV #M.LGB2-.-6,R1
	ADD PC,R1
	JSR PC,MULF
	MOV 2(SP),R0		;SAVE IT TWICE ON STACK
	JSR PC,M.MOVE
	JSR PC,M.MOVE
	MOV SP,R0		;LET TEM1(STK)=A0-Y
	MOV #M.MA0-.-6,R1
	ADD PC,R1
	JSR PC,ADDF
	MOV SP,R0
	MOV R0,R1
	JSR PC,NEGF
	INC 12(SP)		;LET NUM(STK)=2Y
	MOV 16(SP),R0
	MOV R0,R1		;LET Y=Y^2
	JSR PC,MULF
;AT THIS POINT DEST =Y^2, AND A0-Y AND 2Y ARE ON STACK
	MOV 16(SP),R0		;LET DEST=DEST+B1
	MOV #M.BB1-.-6,R1
	ADD PC,R1
	JSR PC,ADDF
	MOV #M.AA1-.-6,R0	;MOVE AA1 ON STACK
	ADD PC,R0
	JSR PC,M.MOVE
	MOV SP,R0		;LET A1=A1/DEST
	MOV 24(SP),R1
	JSR PC,DIVF
	MOV SP,R0		;LET A1=A1+TEM1(STK). TEM1=A0-Y
	MOV R0,R1
	ADD #6,R1
	JSR PC,ADDF
	MOV SP,R1		;LET NUM(STK)=;A1. NUM=2Y
	MOV R1,R0
	ADD #14,R0
	JSR PC,DIVF
	ADD #14,SP		;POP TO NUM
	MOV SP,R0
	MOV #M.ONE-.-6,R1	;LET NUM=NUM+1
	ADD PC,R1
	JSR PC,ADDF
	MOV SP,R0
	MOV R0,R1
	JSR PC,MULF		;LET NUM=NUM^2
	MOV SP,R1
	MOV 10(SP),R0		;MOVE NUM TO DEST
	JSR PC,MOVF
	MOV 10(SP),R0		;EXP(DEST)=EXP(DEST)+INT
	ADD 6(SP),4(R0)
	JMP M.OUT



;EVALS A POLYNOMIAL ACCORDING TO PARAMETERS ON THE STACK
;# OF CONSTANTS
;LOC OF X ON STACK
;LOC OF U1 ON STACK;LOC OF DEST ON STACK
;STARTING LOC OF CONSTANTS
;LENGTH IS 39 WORDS
;TIME IS 460N - 180 WHERE N IS THE NUMBER OF CONSTANTS
M.DOPO:	SUB #2,2(SP)
	MOV 10(SP),R0		;LET DEST=DEST*K(1)
	MOV 12(SP),R1
	MOV R0,-(SP)
	JSR PC,MULF
M.LOOP:	ADD #6,14(SP)		;UPDATE CPNSTANT POINTER
	MOV @SP,R0		;DEST = DEST+K(N)
	MOV 14(SP),R1
	JSR PC,ADDF
	TST 4(SP)		;TEST THE COUNTER
	BEQ M.HANK		;IF IT ='S 0 THEN GOTO HANK
	MOV @SP,R0		;DEST=DEST*U
	MOV 10(SP),R1
	JSR PC,MULF
	DEC 4(SP)		;CNTR=CNTR-1
	BR M.LOOP		;LOOP DONE?
M.HANK:	MOV @SP,R0		;YES. DIVIDE BY X
	MOV 6(SP),R1
	JSR PC,MULF
	TST (SP)+
	MOV (SP)+,R3		;SAVE SAVED R5
	ADD #26,SP
	MOV	R3,PC
;FOLLOWING SUBROUTINE PUSHES THE POINTERS, WHICH ARE
;CONTAINED IN R0 AND R1 ONTO THE STACK, ALONG WITH A FLAG.
;IT ALSO TRANSFERS THE SOURCE FLOATING WORD TO THE DSTINATION
;FLOATING WORD.
M.INIT:	MOV (SP)+,R3		;GET RETURN ADDRESS
	CLR -(SP)		;CLEAR A FLAG
M.INI3:	MOV R1,-(SP)		;PUSH ON SOURCE POINTER
	MOV R0,-(SP)		;PUSH ON DEST POINTER
	JSR PC,MOVF		;MOVE SOURCE TO DEST
	MOV	R3,PC		;RETURN REAL FAST
M.INI2:	MOV	(SP)+,R3	;GET THE RETURN ADDRESS
	BR	M.INI3		;REJOIN THE MAIN ROUTINE

;SETS UP DOPOL
;POINTER TO DEST IN R0,# OF CONSTANTS IN R3
;LOC OF FIRST CONSTANT IN R4
;SETS UP STACK IN FOLLOWING MANNER:
; STARTING LOC OF CONSTANTS (TOP OF STACK)
;				    LOC  OF DESTINATION
;				    LOC OF THE CONTENTS OF DESTINATION SQUARED
;				    NUMBER OF CONSTANTS
;LENGTH IS 26 WORDS
;TIME IS 381 CYCLES
M.SETU:	MOV	(SP)+,R2	;GET THE RETURN ADDRESS
	JSR PC,M.MOVE		;SAVE X ON STACK
	MOV R2,-(SP)
	MOV R4,-(SP)
	MOV R3,-(SP)
	MOV R0,-(SP)		;SAVE REGISTERS
	MOV R0,R1
	JSR PC,MULF
	MOV (SP)+,R0
	MOV (SP)+,R3
	MOV (SP)+,R4
	MOV (SP)+,R2
	JSR PC,M.MOVE		;SAVE  X^2 ON STACK
	MOV R4,-(SP)		;PUSH LOC OF CONSTANT POINTER
	MOV R0,-(SP)		;DEST POINTER
	MOV SP,R0		
	ADD #4,R0
	MOV R0,-(SP)		;U1 POINTER
	ADD #6,R0
	MOV R0,-(SP)		;X POINTER
	MOV R3,-(SP)		;CNTR
	MOV	R2,PC
;COMPUTES THE FRACTIONAL PART OF SOME NUMBER TIMES DESTINATION.
;R1 POINTS TO THE NUMBER
;R0 POINTS TO THE DESTINATION
;COMPUTATION IS DONE AS FOLLOWS: DEST=DEST-INT(DEST)
;LENGTH IS 27 WORDS
;TIME IS 788 CYCLES (WORST)

M.FRAC:	MOV 2(SP),R0
M.FRA1:	ADD PC,R1
	JSR PC,MULF
	MOV (SP)+,2(SP)		;SAVE SAVED R5
	MOV @SP,R1		;PUT DEST POINTER IN R1
	TST -(SP)		;MAKE ROOM FOR THE INTEGER WHICH WILL BE PUT THERE
	MOV SP,R0		;SET UP DESTINATION
	JSR PC,FIX		;FIX DEST AND PUT RESULT ON STACK
	MOV SP,R1		;MAKE R1 POINT TO INT
	SUB #6,SP		;MAKE ROOM FOR THE FLOATED INT WHICH WILL BE PUT THERE
	MOV SP,R0
	JSR PC,FLT		;FLOAT THE INT AND PUT RESULT ON STACK
	MOV SP,R1		;LET DEST=DEST-INT(DEST)
	MOV 10(SP),R0
	JSR PC,SUBF
	ADD #6,SP		;POP PAST FLOATED INT
	JMP	@4(SP)		;RETURN TO CALLER
;STORAGE
;SIN
M.TAB:	M.EVAL-M.TTX-4,M.Q2-M.TTX-4,M.Q3-M.TTX-4,M.Q4-M.TTX-4
M.PIE2:	140671,050574,100000	;2/PI
M.ONE:	000000,040000,100001	;1.
M.A11:	017676,106516,077756	;-.00000341817225
	175316,051777,077764	;.00016021713430
	156214,131513,077771	;-.00468162023910
	167376,050632,077775	;.07969258728630
	006165,126521,100000	;-.64596409264401
M.PI2:	166516,062207,100001	;PI/2

;ARCTAN
M.OT32:	050574,042230,077777	;2-SQT(3)
M.ROT3:	165640,067331,100001	;SQT(3)
M.PI6:	044336,041405,100000	;PI/6
M.TAB2:	113440,060462,077775	;.09491954952
	107717,133556,077776	;-.14173460613
	155646,063141,077776	;.19996534780
	131012,125252,077777	;-.33333289364
	177776,077777,100000	;.99999999843
;EXPONENTIAL
M.LOG2:	016624,056125,100001	;LOG(2)E
M.LGB2:	005776,054271,077777	;(LN 2)/2
M.MA0:	037347,117741,100004	;-12.015016753875
M.AA1:	041565,132306,100012	;-601.8042666979565
M.BB1:	026570,074056,100006	;60.09019073192600
;SQUARE ROOT
M.ROOT:	074626,055202,100001	;SQRT(2)
M.AA:	125672,065324,077777	;.41730760
M.BB:	067102,045612,100000	;.59016207
;LOG
M.RT2B:	074626,055202,100000	;SQT(2)/2
M.LOGE:	005776,054271,100000	;LN 2
M.TABL:	125112,046414,077777	;.300974506336
	007411,063120,077777	;.399659100019
	066333,052525,100000	;.666669470507
	177772,077777,100001	;1.999999993788
	.EOT
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           